package com.paradogs.framework.core.msg;

import com.baidu.bjf.remoting.protobuf.Codec;
import com.baidu.bjf.remoting.protobuf.FieldType;
import com.baidu.bjf.remoting.protobuf.ProtobufProxy;
import com.baidu.bjf.remoting.protobuf.annotation.Protobuf;
import com.google.protobuf.InvalidProtocolBufferException;
import com.paradogs.framework.core.utils.BeanUtils;
import com.paradogs.framework.core.utils.ProtoUtils;
import com.paradogs.framework.core.utils.RandomUtils;
import com.paradogs.framework.core.utils.RouteUtils;
import io.netty.buffer.ByteBuf;
import lombok.Data;
import lombok.ToString;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;


/**
 * @author: yumi
 * @date: 2023-02-08  13:41
 * @Description: 消息头
 */
@Data
public class MsgHeader implements IMsgSerializable {

    /**
     * 消息唯一 ID，用于请求 - 响应
     */
    @Protobuf(fieldType = FieldType.INT64, order = 1, required = false)
    private Long id = RandomUtils.spawnSnowId();

    /**
     * 消息类型，替代路由地址（java 使用类型对应，nodejs 可以使用字符串对应方法）
     * 待优化，路由转 cmd api
     */
//    @Protobuf(fieldType = FieldType.INT32, order = 2, required = false)
//    private int cmd;

    /**
     * 消息路由，可通过字典转换为 cmd
     */
    @Protobuf(fieldType = FieldType.STRING, order = 2, required = false)
    private String route;

    /**
     * 回复的消息 ID
     */
    @Protobuf(fieldType = FieldType.STRING, order = 3, required = false)
    private String sendServer;

    /**
     * 回复的消息 ID
     */
    @Protobuf(fieldType = FieldType.INT64, order = 4, required = false)
    private Long replyMsgId;

    /**
     * 玩家 ID
     */
    @Protobuf(fieldType = FieldType.INT64, order = 5, required = false)
    private Long pId;

//    /**
//     * 消息生成的时间戳
//     */
//    @Protobuf(fieldType = FieldType.INT64, order = 3, required = false)
//    private Long timestamp;


    /**
     * 序列化（编码）
     * ps: netty 的 codec 最终会捕获异常转换成 EncoderException
     * @param out
     */
    @Override
    public void serialization(ByteBuf out) throws IOException {
        byte[] bytes = ProtoUtils.encode(this);
        out.writeShort(bytes.length);
        out.writeBytes(bytes);
    }

    /**
     * 反序列化（解码）
     * @param in
     * @throws InvalidProtocolBufferException
     */
    @Override
    public void deserialization(ByteBuf in) throws IOException {
        byte[] bytes = new byte[in.readShort()];
        in.readBytes(bytes);
        this.deserialization(bytes);
    }

    @Override
    public void deserialization(byte[] bytes) throws IOException {
        MsgHeader msgHeader = ProtoUtils.decode(bytes, this.getClass());
        BeanUtils.copyProperties(msgHeader, this);
    }

    public String getServer() {
        return this.route.substring(0, this.route.indexOf(RouteUtils.SERVER_SEPARATOR));
    }

}
